/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "曲线视口工作区.h"
#include "ui曲线编辑器.h"


static std::vector<C_节点基类*> gNode;


static C_Widget* g关键帧曲线控制点弹出菜单 = nullptr;




static bool on_曲线编辑框打开(C_Widget* self, bool show) {
	C_工作区页面* 工作区 = dynamic_cast<C_工作区页面*>(self);
	C_曲线编辑视口::g当前操作曲线视口 = (C_曲线编辑视口*)(工作区->mui_视口页面);

	if (show) {
		S_框架::m_工作区属性面板渲染层ID分配.f_置组件渲染层(工作区->mui_属性栏);
		S_框架::m_工作区属性面板渲染层ID分配.f_置组件渲染层(工作区->mui_状态条);

		f_曲线视口_重构状态条(工作区->mui_状态条, 工作区->mui_视口页面);
	}
	else {
		S_框架::m_工作区属性面板渲染层ID分配.f_移除渲染层组件(工作区->mui_属性栏);
		S_框架::m_工作区属性面板渲染层ID分配.f_移除渲染层组件(工作区->mui_状态条);
	}
	
	return false;
}

static bool on_控制点类型切换菜单项(C_Widget* self, const std::u16string name, uint16 id) {
	uint32 控制点类型 = 0;
	if (name == u"自动") {
		控制点类型 = DEF_CONTORL_POINT_AUTO;
	}
	else if (name == u"自由") {
		控制点类型 = DEF_CONTORL_POINT_FREE;
	}
	else if (name == u"对齐") {
		控制点类型 = DEF_CONTORL_POINT_ALGNED;
	}
	else if (name == u"向量") {
		控制点类型 = DEF_CONTORL_POINT_VECTOR;
	}

	f_工作区_切换控制点类型(控制点类型);
	return false;
}


void f_工作区页面_曲线视口初始化(S_UI渲染环境& ctx) {
	S_菜单创建参数 菜单创建参数 = {
		on_控制点类型切换菜单项, {
			{u"自动", u"",  u"", nullptr},
		    {u"自由", u"",  u"", nullptr},
		    {u"对齐", u"",  u"", nullptr},
		    {u"向量", u"",  u"", nullptr},
		}
	};

	g关键帧曲线控制点弹出菜单 = f_ui_创建菜单(ctx, e_纵向, 菜单创建参数);
}

C_工作区页面* f_工作区_创建曲线视口(S_UI渲染环境& ctx) {
	C_曲线编辑视口* ui曲线编辑视口 = f_工作区页面_创建曲线视口(ctx);
	
	auto* 滚动窗口 = f_ui_创建滚动框(ctx, true, true, ui曲线编辑视口);
	滚动窗口->mf_鼠标滚轮 = nullptr;

	ui曲线编辑视口->mui_状态条->f_重构();



	S_鼠标键位映射* 鼠标键位 = f_widget_init_鼠标键位映射();
	鼠标键位->event = f_工作区_横向缩放页面视口;
	鼠标键位->鼠标按键[0] = E_Input_鼠标按键::e_滚轮;
	鼠标键位->鼠标状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	鼠标键位->键盘按键[0] = S_InputKey::e_KEY_左SHIFT;
	鼠标键位->键盘状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	鼠标键位->发生组件 = ui曲线编辑视口;
	f_ui_注册鼠标快捷键(ui曲线编辑视口, (S_键位映射*)鼠标键位);

	鼠标键位 = f_widget_init_鼠标键位映射();
	鼠标键位->event = f_工作区_纵向缩放页面视口;
	鼠标键位->鼠标按键[0] = E_Input_鼠标按键::e_滚轮;
	鼠标键位->鼠标状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	鼠标键位->键盘按键[0] = S_InputKey::e_KEY_左CTRL;
	鼠标键位->键盘状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	鼠标键位->发生组件 = ui曲线编辑视口;
	f_ui_注册鼠标快捷键(ui曲线编辑视口, (S_键位映射*)鼠标键位);

	鼠标键位 = f_widget_init_鼠标键位映射();
	鼠标键位->event = f_工作区_缩放页面视口;
	鼠标键位->鼠标按键[0] = E_Input_鼠标按键::e_滚轮;
	鼠标键位->鼠标状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	鼠标键位->发生组件 = ui曲线编辑视口;
	f_ui_注册鼠标快捷键(ui曲线编辑视口, (S_键位映射*)鼠标键位);

	鼠标键位 = f_widget_init_鼠标键位映射();
	鼠标键位->event = f_曲线页面工作区_拖拽时间帧;
	鼠标键位->鼠标按键[0] = E_Input_鼠标按键::e_左键;
	鼠标键位->鼠标状态[0] = DEF_按键状态_放开;
	鼠标键位->发生组件 = ui曲线编辑视口;
	f_ui_注册鼠标快捷键(ui曲线编辑视口, (S_键位映射*)鼠标键位);

	S_拖拽键位映射* 拖拽键位 = f_widget_init_拖放键位映射();
	拖拽键位->event = f_曲线页面工作区_拖拽时间帧;
	拖拽键位->鼠标按键[0] = E_Input_鼠标按键::e_左键;
	拖拽键位->鼠标状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	拖拽键位->发生组件 = ui曲线编辑视口;
	f_ui_注册鼠标快捷键(ui曲线编辑视口, (S_键位映射*)拖拽键位);



	鼠标键位 = f_widget_init_鼠标键位映射();
	鼠标键位->event = f_工作区_准备框选控制点;
	鼠标键位->鼠标按键[0] = E_Input_鼠标按键::e_右键;
	鼠标键位->鼠标状态[0] = DEF_按键状态_按下;
	鼠标键位->发生组件 = ui曲线编辑视口;
	f_ui_注册鼠标快捷键(滚动窗口, (S_键位映射*)鼠标键位);

	鼠标键位 = f_widget_init_鼠标键位映射();
	鼠标键位->event = f_工作区_框选控制点;
	鼠标键位->鼠标按键[0] = E_Input_鼠标按键::e_右键;
	鼠标键位->鼠标状态[0] = DEF_按键状态_放开;
	鼠标键位->发生组件 = ui曲线编辑视口;
	f_ui_注册鼠标快捷键(滚动窗口, (S_键位映射*)鼠标键位);

	鼠标键位 = f_widget_init_鼠标键位映射();
	鼠标键位->event = f_工作区_完成移动控制点;
	鼠标键位->鼠标按键[0] = E_Input_鼠标按键::e_左键;
	鼠标键位->鼠标状态[0] = DEF_按键状态_放开;
	鼠标键位->发生组件 = ui曲线编辑视口;
	f_ui_注册鼠标快捷键(滚动窗口, (S_键位映射*)鼠标键位);


	拖拽键位 = f_widget_init_拖放键位映射();
	拖拽键位->event = f_工作区_拖拽曲线视口选框;
	拖拽键位->鼠标按键[0] = E_Input_鼠标按键::e_右键;
	拖拽键位->鼠标状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	拖拽键位->发生组件 = ui曲线编辑视口;
	f_ui_注册鼠标快捷键(滚动窗口, (S_键位映射*)拖拽键位);



	S_键盘键位映射* 快捷键 = f_widget_init_键盘位映射();
	快捷键->event = f_工作区_开启移动控制点;
	快捷键->键盘按键[0] = S_InputKey::e_KEY_G;
	快捷键->键盘状态[0] = DEF_按键状态_按下;
	快捷键->发生组件 = ui曲线编辑视口;
	f_ui_注册键盘快捷键(滚动窗口, 快捷键);

	快捷键 = f_widget_init_键盘位映射();
	快捷键->event = on_工作区_删除控制点;
	快捷键->键盘按键[0] = S_InputKey::e_KEY_X;
	快捷键->键盘状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	快捷键->发生组件 = ui曲线编辑视口;
	f_ui_注册键盘快捷键(滚动窗口, 快捷键);


	快捷键 = f_widget_init_键盘位映射();
	快捷键->event = f_工作区_打开曲线控制点类型切换菜单;
	快捷键->键盘按键[0] = S_InputKey::e_KEY_V;
	快捷键->键盘状态[0] = DEF_按键状态_按下;
	快捷键->发生组件 = ui曲线编辑视口;
	f_ui_注册键盘快捷键(ui曲线编辑视口, 快捷键);




	C_工作区页面* 工作区 = new C_工作区页面(E_工作区类型::e_曲线视口, ctx, E_方向::e_横向, ui曲线编辑视口, ui曲线编辑视口->mui_状态条);
	工作区->mf_打开关闭 = on_曲线编辑框打开;


	S_框架::m_工作区属性面板渲染层ID分配.f_置组件渲染层(工作区->mui_属性栏);
	S_框架::m_工作区属性面板渲染层ID分配.f_置组件渲染层(工作区->mui_状态条);


	f_曲线视口_重构状态条(工作区->mui_状态条, ui曲线编辑视口);
	return 工作区;
}

void f_曲线视口页面_联动更新() {
	//for (auto& e : C_曲线编辑视口::g_曲线视口页面) {
	//	if (e->m_是否未绘制 == false) {
	//		f_时间工作区_刷新时间线绘制(
	//			C_曲线编辑视口::g当前操作曲线视口,
	//			C_曲线编辑视口::g当前操作曲线视口->m_时间线绘制,
	//			f_NodeCtx_get帧().当前帧,
	//			C_曲线编辑视口::g当前操作曲线视口->m_父部件->m_Size.y);
	//	}
	//}
	f_曲线编辑视口_刷新绘制();
}

static void f_提取骨骼动画曲线(std::vector<S_Object*>& obs) {
	for (auto& e : obs) {
		auto* ob = static_cast<S_物体*>(e);

		if (ob->m_Type == E_物体类型::t_骨骼) {
			//if (ob->m_位置 && ob->m_位置->count)
				//for (auto* c = e->m_位置->曲线通道; c; c = c->ptr_尾) {
				//	g当前操作曲线视口->m_动画曲线.push_back(DEF_物体动画曲线(c));
				//}

			//if (ob->m_旋转 && ob->m_旋转->count)
				//for (auto* c = e->m_旋转->曲线通道; c; c = c->ptr_尾) {
				//	g当前操作曲线视口->m_动画曲线.push_back(DEF_物体动画曲线(c));
				//}

			//if (ob->m_缩放 && ob->m_缩放->count)
				//for (auto* c = e->m_缩放->曲线通道; c; c = c->ptr_尾) {
				//	g当前操作曲线视口->m_动画曲线.push_back(DEF_物体动画曲线(c));
				//}

			f_提取骨骼动画曲线(e->m_子物体);
		}
	}
}

void f_曲线视口工作区_设置当前编辑节点() {
	std::vector<C_节点基类*> nodes = f_global_get激活节点();
	gNode = nodes;

	if (C_曲线编辑视口::g当前操作曲线视口) {
		C_曲线编辑视口::g当前操作曲线视口->m_动画曲线.clear();

		for (auto& node : gNode) {
			auto* ob = node->f_虚拟体();
			
			if (ob) {
				if (ob->m_子物体.size()) {
					
				}
				if (ob->m_位置) C_曲线编辑视口::g当前操作曲线视口->m_动画曲线.push_back(ob->m_位置);
				if (ob->m_旋转) C_曲线编辑视口::g当前操作曲线视口->m_动画曲线.push_back(ob->m_旋转);
				if (ob->m_缩放) C_曲线编辑视口::g当前操作曲线视口->m_动画曲线.push_back(ob->m_缩放);

			}

			node->f_getAN曲线();
		}

		C_曲线编辑视口::g当前操作曲线视口->f_重建曲线绘制();
	}
}

void f_曲线视口工作区_设置当前编辑物体() {
	if (C_曲线编辑视口::g当前操作曲线视口) {
		C_曲线编辑视口::g当前操作曲线视口->m_动画曲线.clear();

		for (auto& ob : S_框架::g_拾取物体) {
			if (ob->m_位置) C_曲线编辑视口::g当前操作曲线视口->m_动画曲线.push_back(ob->m_位置);
			if (ob->m_旋转) C_曲线编辑视口::g当前操作曲线视口->m_动画曲线.push_back(ob->m_旋转);
			if (ob->m_缩放) C_曲线编辑视口::g当前操作曲线视口->m_动画曲线.push_back(ob->m_缩放);
		}

		C_曲线编辑视口::g当前操作曲线视口->f_重建曲线绘制();
	}
}

E_事件是否传递 f_工作区_打开曲线控制点类型切换菜单(C_Widget* self, E_键位执行状态 状态) {
	f_ui_打开弹出窗口(g关键帧曲线控制点弹出菜单, C_Widget::g_鼠标.gPos - 10);
	return E_事件是否传递::e_事件传递_终止;
}








